﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once

#include "GcmpModelInterface.h"
#include "IElement.h"

namespace gcmp
{
    class IPresetParameterManager;
    class UniIdentity;
    class IParameter;
    class IPresetValuesGroupIdGenerator;
    /// \brief 预设参数管理器
    ///
    /// 预设参数用于记录用户最近一次创建构件时使用的参数，再次创建时默认使用上次的记录值。
    /// 举例：用户通过命令创建墙构件时，在属性面板手动设置了墙的高度为3000，那么下次再通过命令创建墙构件时，墙的高度参数默认为3000，无需用户再次手动输入。
    /// 预设参数以构件类别和预设参数组Id为索引进行管理，以支持在同一类别下，不同参数组Id，分别记录预设参数。
    class GCMP_MODEL_INTERFACE_EXPORT IPresetParameterManager : public IElement
    {
        DEFINE_CAST_DERIVED(gcmp::IPresetParameterManager, gcmp::IElement);

    public:

#pragma region static methods
        /// \brief 获取预设参数管理器，每个文档有且仅有一个
        /// \param pDoc 文档指针
        /// \return 预设参数管理器
        static IPresetParameterManager* Get(const IDocument* pDoc);

        /// \brief 注册预设参数组Id生成器
        ///
        /// \param pPresetValuesGroupIdGenerator 预设参数组Id生成器
        /// \return 是否成功
        static bool RegisterPresetValuesGroupIdGenerator(IPresetValuesGroupIdGenerator* pPresetValuesGroupIdGenerator);

        /// \brief 注销预设参数组Id生成器
        ///
        /// \param pPresetValuesGroupIdGenerator 预设参数组Id生成器
        /// \return 是否成功
        static bool UnRegisterPresetValuesGroupIdGenerator(IPresetValuesGroupIdGenerator* pPresetValuesGroupIdGenerator);


#pragma endregion static methods

        /// \brief 获取最近一次创建构件时预设的实例类型Id
        /// \param categoryUid 类别
        /// \param presetValuesGroupId 预设参数组Id 
        /// \param instanceTypeId 返回预设的实例类型Id
        /// \return 是否成功。true：instanceTypeId返回预设值；false：instanceTypeId未设置
        virtual bool GetPresetType(const UniIdentity& categoryUid, Int32 presetValuesGroupId, ElementId& instanceTypeId) const = 0;

        /// \brief 设置最近一次创建构件时预设的实例类型Id
        ///
        /// 如在创建构件时，修改属性面板中的构件类型，则系统会自动记录该类型Id，用户无需显式设置
        /// \param categoryUid 类别
        /// \param presetValuesGroupId 预设参数组Id
        /// \param instanceTypeId 预设的实例类型Id
        /// \return 是否设置成功。
        virtual bool SetPresetType(const UniIdentity& categoryUid, Int32 presetValuesGroupId, ElementId instanceTypeId) = 0;

        /// \brief 获取最近一次创建构件时预设的参数
        /// \param categoryUid 类别
        /// \param presetValuesGroupId 预设参数组Id
        /// \param paramId 参数Id
        /// \return 返回预设参数对象，如果该参数未曾记录过预设值，则返回空指针
        virtual const IParameter* GetPresetParameter(const UniIdentity& categoryUid, 
            Int32 presetValuesGroupId, int parameterId) const = 0;

        /// \brief 设置最近一次创建构件时预设的参数
        ///
        /// 如在创建构件时，修改属性面板中的参数，则系统会自动记录该参数作为预设参数，用户无需显式设置
        /// \param categoryUid 类别
        /// \param presetValuesGroupId 预设参数组Id
        /// \param pParameter 参数
        /// \return 是否设置成功
        virtual bool SetPresetParameter(const UniIdentity& categoryUid, Int32 presetValuesGroupId, 
            const IParameter* pParameter) = 0;

        /// \brief 移除该预设的参数
        /// \param categoryUid 类别
        /// \param presetValuesGroupId 预设参数组Id
        /// \param paramId 参数Id
        /// \return 是否成功
        virtual bool RemovePresetParameter(const UniIdentity& categoryUid, Int32 presetValuesGroupId, int parameterId) = 0;

        /// \brief 获取预设的参数组Id
        ///
        /// \param Element 实例
        /// \return 预设Id
        virtual Int32 GetPresetValuesGroupId(const IElement* pElement);

    public:
        /// \brief 获取Implementation Uid
        ///
        /// \return UniIdentity 返回ImplementationUid
        static UniIdentity GetImplementationUid();
    };
}



